#include "visorlineatiempogl.h"
#include "entrenador.h"
#include "punto3d.h"
#include "cuadrilatero.h"

#define ANCHO 400
#define ALTO  100
#define MARGEN 0
#define RADIO 5

VisorLineaTiempoGL::VisorLineaTiempoGL(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

    //escena.agregar(instrumento->getListaDibujos3d());
    
    ui.visor3d->setEscena(&escena);

    ui.visor3d->establecerVision2d(-10, -10, 420, 120);
   // ui.visor3d->establecerVision2d(0, 0, ANCHO, ALTO, false);

    ui.visor3d->setHerramienta(&herramienta);  

    texturaAro = new Textura(":/entrenador/Resources/aro.png");;
    texturaPunto = new Textura(":/entrenador/Resources/punto.png");;
    escena.agregar(texturaAro);
    escena.agregar(texturaPunto);

    crearEscena();
}

VisorLineaTiempoGL::~VisorLineaTiempoGL()
{

}

void VisorLineaTiempoGL::actualizar()
{
    Instrumento* instrumento = Entrenador::getInstancia()->getInstrumento();
    Interprete* interprete = Entrenador::getInstancia()->getInterprete();

    Patron patron = interprete->getPatron();

    // TODO: recorrer todos los compases
    //Compas compas = patron.getCompas(0);
    int numeroCompases = patron.getNumeroCompases();
	int numeroPulsos = patron.getNumeroPulsos();
	int numeroPiezas = instrumento->getNumeroPiezas();

    //int numeroCompasRelativoAlPatron = interprete->getNumeroCompasRelativoAlPatron();
    //double proporcionCompletadoPatron = interprete->getProporcionCompletadoCompas();

	double separacionX = (ANCHO - 2.0 * MARGEN) / numeroPulsos;
	double separacionY = (ALTO - 2.0 * MARGEN) / numeroPiezas;

    // Linea de instante actual
    double xInicial = MARGEN;
	double yInicial = MARGEN;
	double xFinal = ANCHO - MARGEN;
	double yFinal = ALTO - MARGEN;

    double proporcionX = interprete->getProporcionCompletadaDelPatron();
    double x = xInicial + proporcionX * (xFinal - xInicial);
    Punto3d p1(x, yInicial, 0);
	Punto3d p2(x, yFinal, 0);
    lineaInstanteActual->setVertices(p1, p2);

    // Notas del usuario
    dibujosNotasUsuario->destruir();

    QList<NotaRegistrada> listaNotas = Entrenador::getInstancia()->getListaNotasRegistradasUsuario();
    quint64 milisegundoInicio = interprete->getMilisegundoInicioPatron();
    double milisegundosPorPatron = interprete->getMilisegundosPorPatron();

    foreach (NotaRegistrada notaRegistrada, listaNotas) {

        int indiceY = instrumento->getIndiceNota(notaRegistrada.nota);
        if (indiceY < 0) {
            continue;
        }
        quint64 milisegundo = notaRegistrada.milisegundo;

        double milisegundoRelativo;
        if (milisegundo < milisegundoInicio) {
            milisegundoRelativo = - (double) (milisegundoInicio - milisegundo);
        } else {
            milisegundoRelativo = milisegundo - milisegundoInicio;
        }
        double proporcionTiempo = milisegundoRelativo / milisegundosPorPatron;

        double x = xInicial + proporcionTiempo * (xFinal - xInicial) ;
        double y = yInicial + indiceY * separacionY; 
        QRectF renctanguloRealNota(x - RADIO, y - RADIO, RADIO * 2, RADIO * 2);

        QColor color = Entrenador::getInstancia()->getColorNota(notaRegistrada.nota);
        color.setAlpha(175);

        Cuadrilatero* cuadrilatero = new Cuadrilatero();
        cuadrilatero->setRectanguloXY(renctanguloRealNota);
        cuadrilatero->setColor(color);
        cuadrilatero->setTextura(texturaPunto);
        dibujosNotasUsuario->agregar(cuadrilatero);
    }

    ui.visor3d->updateGL();
}

void VisorLineaTiempoGL::crearEscena()
{
    escena.destruir();

	Instrumento* instrumento = Entrenador::getInstancia()->getInstrumento();
	Interprete* interprete = Entrenador::getInstancia()->getInterprete();

    Patron patron = interprete->getPatron();

    // TODO: recorrer todos los compases
    //Compas compas = patron.getCompas(0);

    int numeroCompases = patron.getNumeroCompases();
	int numeroPulsos = patron.getNumeroPulsos();
	int numeroPiezas = instrumento->getNumeroPiezas();

	double separacionX = (ANCHO - 2.0 * MARGEN) / numeroPulsos;
	double separacionY = (ALTO - 2.0 * MARGEN) / numeroPiezas;

	double xInicial = MARGEN;
	double yInicial = MARGEN;
	double xFinal = ANCHO - MARGEN;
	double yFinal = ALTO - MARGEN;

    //painter->setPen(Qt::gray);
    // Lineas de separacion horizontales
    for (int i = 0; i <= numeroPiezas; i++) {
	    double y = MARGEN + i * separacionY;
	    Punto3d p1(xInicial, y, 0);
	    Punto3d p2(xFinal, y, 0);
        Linea* linea = new Linea(p1, p2);
        linea->setColor(Qt::gray);
        escena.agregar(linea);
    }
	
    // Lineas de separacion verticales
    for (int i = 0; i <= numeroPulsos; i++) {
	    double x = MARGEN + i * separacionX;
	    Punto3d p1(x, yInicial, 0);
	    Punto3d p2(x, yFinal, 0);
        Linea* linea = new Linea(p1, p2);
        escena.agregar(linea);
    }

    double xInicialCompas = xInicial;

    // Notas del compas de entrenamiento
    for (int indiceCompas = 0; indiceCompas < numeroCompases; indiceCompas++) {
        
        Compas compas = patron.getCompas(indiceCompas);
        for (int i = 0, n = compas.getNumeroNotas(); i < n; i++) {
            NotaCompas nota = compas.getNota(i);
            if (!nota.esValida()) {
                continue;
            }

            int indiceY = instrumento->getIndiceNota(nota.getNombreNota());

            double proporcionDivision = ((double) nota.getDivision()) / nota.getDivisiones();
            double x = xInicialCompas + (nota.getPulso() + proporcionDivision) * separacionX;
            double y = yInicial + indiceY * separacionY; 
            QRectF renctanguloRealNota(x - RADIO, y - RADIO, RADIO * 2, RADIO * 2);
            Cuadrilatero* cuadrilatero = new Cuadrilatero();
            cuadrilatero->setRectanguloXY(renctanguloRealNota);
            cuadrilatero->setColor(Qt::gray);
            cuadrilatero->setTextura(texturaAro);
            escena.agregar(cuadrilatero);
        }
        xInicialCompas += compas.getNumeroPulsos() * separacionX;
    }

    // Notas del usuario
    dibujosNotasUsuario = new GrupoDibujos();
    escena.agregar(dibujosNotasUsuario);

    // Linea de instante actual
    lineaInstanteActual = new Linea();
    lineaInstanteActual->setColor(Qt::red);
    escena.agregar(lineaInstanteActual);
}
